﻿

using DualPlaneFR4Paster.Common.Services;
using DualPlaneFR4Paster.Extensions;
using DualPlaneFR4Paster.Models;
using HalconDotNet;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using netDxf.Entities;
using Newtonsoft.Json;
using Prism.Commands;
using Prism.Ioc;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Forms;
using ViewROI;

namespace DualPlaneFR4Paster.ViewModels.Dialogs.Camera
{
    public class CameraProductVisionCalcDialogViewModel : DialogViewModel
    {
        #region 变量
        private readonly IContainerProvider _containerProvider;
        private int floor = 1;
        private string partNum = string.Empty;
        private ICameraService cam1;
        private IGTSCardService Top_A4;
        private IGTSCardService Top_A8;
        private IGTSCardService Bottom_A8;
        CancellationTokenSource source;
        double xjogspeed = 0;
        double yjogspeed = 0;
        double zjogspeed = 0;
        double rjogspeed = 0;
        double z1safe = 0;
        double z2safe = 0;
        double z3safe = 0;
        double z4safe = 0;

        double upCameraGrabPreTime = 0;
        #endregion
        #region 属性
        #region halcon
        #region 1#
        private HImage cameraIamge0;
        public HImage CameraIamge0
        {
            get { return cameraIamge0; }
            set { SetProperty(ref cameraIamge0, value); }
        }
        private bool cameraRepaint0;
        public bool CameraRepaint0
        {
            get { return cameraRepaint0; }
            set { SetProperty(ref cameraRepaint0, value); }
        }
        private ObservableCollection<ROI> cameraROIList0 = new ObservableCollection<ROI>();
        public ObservableCollection<ROI> CameraROIList0
        {
            get { return cameraROIList0; }
            set { SetProperty(ref cameraROIList0, value); }
        }
        private HObject cameraAppendHObject0;
        public HObject CameraAppendHObject0
        {
            get { return cameraAppendHObject0; }
            set { SetProperty(ref cameraAppendHObject0, value); }
        }
        private HMsgEntry cameraAppendHMessage0;
        public HMsgEntry CameraAppendHMessage0
        {
            get { return cameraAppendHMessage0; }
            set { SetProperty(ref cameraAppendHMessage0, value); }
        }
        private Tuple<string, object> cameraGCStyle0;
        public Tuple<string, object> CameraGCStyle0
        {
            get { return cameraGCStyle0; }
            set { SetProperty(ref cameraGCStyle0, value); }
        }
        #endregion
        #endregion
        private bool liveToggleButtonIsChecked;
        public bool LiveToggleButtonIsChecked
        {
            get { return liveToggleButtonIsChecked; }
            set { SetProperty(ref liveToggleButtonIsChecked, value); }
        }
        private bool isBusy;
        public bool IsBusy
        {
            get { return isBusy; }
            set { SetProperty(ref isBusy, value); }
        }
        private ObservableCollection<AxisPointDisp> pointList1;
        public ObservableCollection<AxisPointDisp> PointList1
        {
            get { return pointList1; }
            set { SetProperty(ref pointList1, value); }
        }
        private double mark1ThresholdMaxGray;
        public double Mark1ThresholdMaxGray
        {
            get { return mark1ThresholdMaxGray; }
            set { SetProperty(ref mark1ThresholdMaxGray, value); }
        }
        private double mark1MinArea;
        public double Mark1MinArea
        {
            get { return mark1MinArea; }
            set { SetProperty(ref mark1MinArea, value); }
        }
        private double mark1MaxArea;
        public double Mark1MaxArea
        {
            get { return mark1MaxArea; }
            set { SetProperty(ref mark1MaxArea, value); }
        }
        private double mark2ThresholdMaxGray;
        public double Mark2ThresholdMaxGray
        {
            get { return mark2ThresholdMaxGray; }
            set { SetProperty(ref mark2ThresholdMaxGray, value); }
        }
        private double mark2MinArea;
        public double Mark2MinArea
        {
            get { return mark2MinArea; }
            set { SetProperty(ref mark2MinArea, value); }
        }
        private double mark2MaxArea;
        public double Mark2MaxArea
        {
            get { return mark2MaxArea; }
            set { SetProperty(ref mark2MaxArea, value); }
        }
        #endregion
        #region 命令
        private DelegateCommand<object> cameraOperateCommand;
        public DelegateCommand<object> CameraOperateCommand =>
            cameraOperateCommand ?? (cameraOperateCommand = new DelegateCommand<object>(ExecuteCameraOperateCommand));
        private DelegateCommand<object> liveGrabCommand;
        public DelegateCommand<object> LiveGrabCommand =>
            liveGrabCommand ?? (liveGrabCommand = new DelegateCommand<object>(ExecuteLiveGrabCommand));
        private DelegateCommand findBoardOrgCommand;
        public DelegateCommand FindBoardOrgCommand =>
            findBoardOrgCommand ?? (findBoardOrgCommand = new DelegateCommand(ExecuteFindBoardOrgCommand));
        private DelegateCommand<AxisPointDisp> pointList1JumpPosCommand;
        public DelegateCommand<AxisPointDisp> PointList1JumpPosCommand =>
            pointList1JumpPosCommand ?? (pointList1JumpPosCommand = new DelegateCommand<AxisPointDisp>(ExecutePointList1JumpPosCommand));
        private DelegateCommand calculateCommand;
        public DelegateCommand CalculateCommand =>
            calculateCommand ?? (calculateCommand = new DelegateCommand(ExecuteCalculateCommand));
        private DelegateCommand<object> createMarkROICommand;
        public DelegateCommand<object> CreateMarkROICommand =>
            createMarkROICommand ?? (createMarkROICommand = new DelegateCommand<object>(ExecuteCreateMarkROICommand));
        private DelegateCommand<object> findMarkCommand;
        public DelegateCommand<object> FindMarkCommand =>
            findMarkCommand ?? (findMarkCommand = new DelegateCommand<object>(ExecuteFindMarkCommand));
        private DelegateCommand<object> textBoxLostFocusCommand;
        public DelegateCommand<object> TextBoxLostFocusCommand =>
            textBoxLostFocusCommand ?? (textBoxLostFocusCommand = new DelegateCommand<object>(ExecuteTextBoxLostFocusCommand));

        void ExecuteTextBoxLostFocusCommand(object obj)
        {
            using var db = new DTContext(partNum);
            switch (obj.ToString())
            {
                case "Mark1ThresholdMaxGray":
                    {
                        var v1 = db.MParams.FirstOrDefault(p => p.Name == "Mark1ThresholdMaxGray" && p.Floor == floor);
                        if (v1 != null)
                        {
                            v1.Value = Mark1ThresholdMaxGray.ToString();
                            db.SaveChanges();
                        }
                    }
                    break;
                case "Mark1MinArea":
                    {
                        var v1 = db.MParams.FirstOrDefault(p => p.Name == "Mark1MinArea" && p.Floor == floor);
                        if (v1 != null)
                        {
                            v1.Value = Mark1MinArea.ToString();
                            db.SaveChanges();
                        }
                    }
                    break;
                case "Mark1MaxArea":
                    {
                        var v1 = db.MParams.FirstOrDefault(p => p.Name == "Mark1MaxArea" && p.Floor == floor);
                        if (v1 != null)
                        {
                            v1.Value = Mark1MaxArea.ToString();
                            db.SaveChanges();
                        }
                    }
                    break;
                case "Mark2ThresholdMaxGray":
                    {
                        var v1 = db.MParams.FirstOrDefault(p => p.Name == "Mark2ThresholdMaxGray" && p.Floor == floor);
                        if (v1 != null)
                        {
                            v1.Value = Mark2ThresholdMaxGray.ToString();
                            db.SaveChanges();
                        }
                    }
                    break;
                case "Mark2MinArea":
                    {
                        var v1 = db.MParams.FirstOrDefault(p => p.Name == "Mark2MinArea" && p.Floor == floor);
                        if (v1 != null)
                        {
                            v1.Value = Mark2MinArea.ToString();
                            db.SaveChanges();
                        }
                    }
                    break;
                case "Mark2MaxArea":
                    {
                        var v1 = db.MParams.FirstOrDefault(p => p.Name == "Mark2MaxArea" && p.Floor == floor);
                        if (v1 != null)
                        {
                            v1.Value = Mark2MaxArea.ToString();
                            db.SaveChanges();
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        void ExecuteFindMarkCommand(object obj)
        {
            if (CameraIamge0 != null)
            {
                CameraAppendHObject0 = null;
                CameraAppendHMessage0 = null;
                int index = int.Parse(obj.ToString());
                string filepath = $"{partNum}\\Camera\\{(floor == 1 ? "Top" : "Bottom")}\\Calc\\Up";
                try
                {
                    HOperatorSet.ReadRegion(out var markRegion, System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, $"Mark{index + 1}Region.hobj"));
                    HOperatorSet.ReduceDomain(CameraIamge0, markRegion, out var imageReduced);
                    double thresholdMaxGray = obj.ToString() == "0" ? Mark1ThresholdMaxGray : Mark2ThresholdMaxGray;
                    double minArea = obj.ToString() == "0" ? Mark1MinArea : Mark2MinArea;
                    double maxArea = obj.ToString() == "0" ? Mark1MaxArea : Mark2MaxArea;
                    ImageCalc.MFindAreaCenter(imageReduced, out var ho_resultRegion, thresholdMaxGray, minArea, maxArea, out var hv_result, out var hv_row, out var hv_column);
                    if (hv_result.I == 1)
                    {
                        CameraGCStyle0 = new Tuple<string, object>("DrawMode", "fill");
                        CameraGCStyle0 = new Tuple<string, object>("Color", "magenta");
                        CameraAppendHObject0 = ho_resultRegion;
                        CameraAppendHMessage0 = new HMsgEntry($"Row:{hv_row.D:f1}", 10, 10, "green", "window", "box", "false", 32, "mono", "true", "false");
                        CameraAppendHMessage0 = new HMsgEntry($"Column:{hv_column.D:f1}", 40, 10, "green", "window", "box", "false", 32, "mono", "true", "false");
                        var result = _dialogHostService.MessageBox(MessageType.Confirm, "信息", $"识别成功，\n确认设为\"Mark{index + 1}\"的基准位置吗？");
                        if (result == ButtonResult.Yes)
                        {
                            string standardfilepath = $"{partNum}\\Camera\\{(floor == 1 ? "Top" : "Bottom")}\\Calc\\Up\\Standard";
                            HOperatorSet.WriteImage(CameraIamge0, "jpeg", 0, System.IO.Path.Combine(System.Environment.CurrentDirectory, standardfilepath, $"Mark{index + 1}.jpg"));
                            HOperatorSet.WriteTuple(hv_row, System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, $"Mark{index + 1}Row.tup"));
                            HOperatorSet.WriteTuple(hv_column, System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, $"Mark{index + 1}Column.tup"));
                        }
                    }
                    else
                    {
                        CameraAppendHMessage0 = new HMsgEntry("识别失败。", 10, 10, "red", "window", "box", "false", 32, "mono", "true", "false");
                    }
                }
                catch (Exception ex)
                {
                    _dialogHostService.MessageBox(MessageType.Message, "信息", ex.Message);
                }
            }
            else
            {
                _dialogHostService.MessageBox(MessageType.Message, "信息", "图像为空");
            }
        }
        void ExecuteCreateMarkROICommand(object obj)
        {
            if (CameraIamge0 != null)
            {
                int index = int.Parse(obj.ToString());
                var result = _dialogHostService.MessageBox(MessageType.Confirm, "信息", $"确定重新画\"Mark{index + 1}\"的区域吗？");
                if (result == ButtonResult.Yes) 
                {
                    CameraAppendHObject0 = null;
                    CameraAppendHMessage0 = null;
                    string filepath = $"{partNum}\\Camera\\{(floor == 1 ? "Top" : "Bottom")}\\Calc\\Up";
                    try
                    {
                        ROI roi = Global.CameraImageViewer.DrawROI(ROI.ROI_TYPE_RECTANGLE1);
                        HRegion markRegion = roi.getRegion();
                        CameraGCStyle0 = new Tuple<string, object>("Color", "yellow");
                        CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                        CameraAppendHObject0 = markRegion;
                        HOperatorSet.WriteRegion(markRegion, System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, $"Mark{index + 1}Region.hobj"));
                    }
                    catch (Exception ex)
                    {
                        _dialogHostService.MessageBox(MessageType.Message, "信息", ex.Message);
                    }
                  
                }
            }
            else
            {
                _dialogHostService.MessageBox(MessageType.Message, "信息", "图像为空");
            }
        }
        void ExecuteCalculateCommand()
        {
            if (CameraIamge0 != null)
            {
                CameraAppendHObject0 = null;
                CameraAppendHMessage0 = null;
                try
                {
                    string filepath = $"{partNum}\\Camera\\{(floor == 1 ? "Top" : "Bottom")}\\Calc\\Up";
                    string calibfilepath = $"Camera\\{(floor == 1 ? "Top" : "Bottom")}\\Calib\\Up";
                    HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, calibfilepath, "CalibHomMat2D.tup"), out var CalibHomMat2D);
                    HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, $"Mark1Row.tup"), out var mark1Row);
                    HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, $"Mark1Column.tup"), out var mark1Column);
                    HOperatorSet.AffineTransPoint2d(CalibHomMat2D, mark1Row, mark1Column, out var mark1x, out var mark1y);
                    var calibPoint = PointList1.FirstOrDefault(p => p.Name == "TopCameraCalib");
                    var mark1Point = PointList1.FirstOrDefault(p => p.Name == "TopCameraMark1");
                    var mark1x1 = mark1Point.X - calibPoint.X + mark1x;
                    var mark1y1 = mark1Point.Y - calibPoint.Y + mark1y;

                    HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, $"Mark2Row.tup"), out var mark2Row);
                    HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, $"Mark2Column.tup"), out var mark2Column);
                    HOperatorSet.AffineTransPoint2d(CalibHomMat2D, mark2Row, mark2Column, out var mark2x, out var mark2y);
                    var mark2Point = PointList1.FirstOrDefault(p => p.Name == "TopCameraMark2");
                    var mark2x1 = mark2Point.X - calibPoint.X + mark2x;
                    var mark2y1 = mark2Point.Y - calibPoint.Y + mark2y;

                    var markMidx = (mark1x1 + mark2x1) / 2;
                    var markMidy = (mark1y1 + mark2y1) / 2;
                    //HOperatorSet.AngleLx(mark1x1, mark1y1, mark2x1, mark2y1, out var hv_Angle);
                    var hv_Angle = new HTuple(Math.Atan2(mark2y1 - mark1y1, mark2x1 - mark1x1));

                    CameraAppendHMessage0 = new HMsgEntry($"X:{markMidx.D:f3}mm", 10, 10, "green", "window", "box", "false", 32, "mono", "true", "false");
                    CameraAppendHMessage0 = new HMsgEntry($"Y:{markMidy.D:f3}mm", 40, 10, "green", "window", "box", "false", 32, "mono", "true", "false");
                    CameraAppendHMessage0 = new HMsgEntry($"R:{hv_Angle.TupleDeg().D:f2}°", 70, 10, "green", "window", "box", "false", 32, "mono", "true", "false");

                    var result = _dialogHostService.MessageBox(MessageType.Confirm, "信息", $"计算完成，\n确认设为载具的基准位置吗？");
                    if (result == ButtonResult.Yes)
                    {
                        HOperatorSet.WriteTuple(markMidx, System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, "MarkMidX.tup"));
                        HOperatorSet.WriteTuple(markMidy, System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, "MarkMidY.tup"));
                        HOperatorSet.WriteTuple(hv_Angle, System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, "MarkMidR.tup"));
                    }
                    HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, "MarkMidX.tup"), out var MarkMidX0);
                    HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, "MarkMidY.tup"), out var MarkMidY0);
                    HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, "MarkMidR.tup"), out var MarkMidR0);
                    var deltaX = markMidx - MarkMidX0;
                    var deltaY = markMidy - MarkMidY0;
                    var deltaR = hv_Angle - MarkMidR0;
                    CameraAppendHMessage0 = new HMsgEntry($"ΔX:{deltaX.D:f3}mm", 10, 230, "magenta", "window", "box", "false", 32, "mono", "true", "false");
                    CameraAppendHMessage0 = new HMsgEntry($"ΔY:{deltaY.D:f3}mm", 40, 230, "magenta", "window", "box", "false", 32, "mono", "true", "false");
                    CameraAppendHMessage0 = new HMsgEntry($"ΔR:{deltaR.TupleDeg().D:f2}°", 70, 230, "magenta", "window", "box", "false", 32, "mono", "true", "false");
                }
                catch (Exception ex)
                {
                    _dialogHostService.MessageBox(MessageType.Message, "信息", ex.Message);
                }
            }
 
            else
            {
                _dialogHostService.MessageBox(MessageType.Message, "信息", "图像为空");
            }


         
        }
        void ExecutePointList1JumpPosCommand(AxisPointDisp point)
        {
            if (point != null)
            {
                var result = _dialogHostService.MessageBox(MessageType.Confirm, "信息", $"确认Jump运动到点\"{point.Alias}\"吗？");
                if (result == ButtonResult.Yes)
                {
                    IsBusy = true;
                    source = new CancellationTokenSource();
                    CancellationToken token = source.Token;
                    Task.Run(() => JumpXYZRAction(token, point), token).ContinueWith(t => { IsBusy = false; });
                }
            }
        }
        void ExecuteFindBoardOrgCommand()
        {
            if (CameraIamge0 != null)
            {
                var result = _dialogHostService.MessageBox(MessageType.Confirm, "信息", "确定重新确认\"载具原点\"的位置吗？");
                if (result == ButtonResult.Yes)
                {
                    string filepath = $"Camera\\{(floor == 1 ? "Top" : "Bottom")}\\Calib\\Up";
                    ROI roi = Global.CameraImageViewer.DrawROI(ROI.ROI_TYPE_CIRCLE);
                    HRegion circle = roi.getRegion();
                    HTuple homMat2D;
                    HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, "CalibHomMat2D.tup"), out homMat2D);
                    HTuple area, row, column;
                    HOperatorSet.AreaCenter(circle, out area, out row, out column);
                    HTuple qx, qy;
                    HOperatorSet.AffineTransPoint2d(homMat2D, row, column, out qx, out qy);

                    using (var db = new DTContext(partNum))
                    {
                        var _calibpoint = db.XYZRPoints.FirstOrDefault(p => p.Name == "TopCameraCalib" && p.Floor == floor);
                        if (_calibpoint != null)
                        {
                            var _boardOrgGrabpoint = db.XYZRPoints.FirstOrDefault(p => p.Name == "TopCameraBoardOrgGrab" && p.Floor == floor);
                            if (_boardOrgGrabpoint != null)
                            {
                                var _point = db.XYZRPoints.FirstOrDefault(p => p.Name == "OrgBoard" && p.Floor == floor);
                                if (_point != null)
                                {

                                    var pointorg = PointList1.FirstOrDefault(p => p.Name == "OrgBoard");
                                    if (pointorg != null)
                                    {
                                        pointorg.X = Math.Round(qx.D + (_boardOrgGrabpoint.X - _calibpoint.X), 3);
                                        pointorg.Y = Math.Round(qy.D + (_boardOrgGrabpoint.Y - _calibpoint.Y), 3);
                                        pointorg.Z = z1safe;
                                        pointorg.R = 0;
                                    }
                                    _point.X = Math.Round(qx.D + (_boardOrgGrabpoint.X - _calibpoint.X), 3);
                                    _point.Y = Math.Round(qy.D + (_boardOrgGrabpoint.Y - _calibpoint.Y), 3);
                                    _point.Z = z1safe;
                                    _point.R = 0;
                                    db.SaveChanges();
                                }
                                _dialogHostService.MessageBox(MessageType.Message, "信息", $"载具原点确认完成\nX:{qx.D + (_boardOrgGrabpoint.X - _calibpoint.X):f3}mm\nX:{qy.D + (_boardOrgGrabpoint.Y - _calibpoint.Y):f3}mm");
                            }
                        }
                    }

                }
            }
            else
            {
                _dialogHostService.MessageBox(MessageType.Message, "信息", "图像为空");
            }
        
        }
        void ExecuteLiveGrabCommand(object isLiveGrab)
        {
            if ((bool)isLiveGrab)
            {
                source = new CancellationTokenSource();
                CancellationToken token = source.Token;
                Task.Run(() => ContinueGrab(token), token);
            }
            else
            {
                if (source != null)
                {
                    source.Cancel();
                }
            }
        }
        void ExecuteCameraOperateCommand(object obj)
        {
            switch (obj.ToString())
            {
                case "拍照":
                    {
                        if (LiveToggleButtonIsChecked)
                        {
                            LiveToggleButtonIsChecked = false;
                            if (source != null)
                            {
                                source.Cancel();
                            }
                            System.Threading.Thread.Sleep(500);
                        }
                        cam1.ImageQueue.Clear();
                        cam1.SetTriggerMode(0);
                        cam1.StartGrabe();
                        Task.Run(() => {
                            int mIndex = 0;
                            while (mIndex < 1)
                            {
                                HObject? hObj;
                                if (cam1.ImageQueue.TryPeek(out hObj))
                                {
                                    cam1.ImageQueue.TryDequeue(out hObj);
                                    CameraIamge0 = new HImage(hObj);
                                    mIndex++;
                                }
                            }
                        }).ContinueWith(t => { cam1.StopGrabe(); });
                    }
                    break;
                case "打开":
                    {
                        OpenFileDialog openFileDialog = new OpenFileDialog();
                        openFileDialog.Filter = "Image Files|*.png;*.bmp;*.jpg;*.tif";
                        if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            HObject image;
                            HOperatorSet.ReadImage(out image, openFileDialog.FileName);
                            CameraIamge0 = new HImage(image);
                        }
                    }
                    break;
                case "增强":
                    {
                        HObject imageScaled;
                        HTuple mult = 255.0 / (255 - 70);
                        HTuple add = -1 * mult * 70;
                        HOperatorSet.ScaleImage(CameraIamge0, out imageScaled, mult, add);
                        CameraIamge0 = new HImage(imageScaled);
                    }
                    break;
                default:
                    break;
            }
        }
        #endregion
        #region 导航
        public override void OnDialogOpened(IDialogParameters parameters)
        {
            floor = parameters.GetValue<int>("Floor");
            partNum = parameters.GetValue<string>("PartNum");
            Title = $"{(floor == 1 ? "上层" : "下层")}-{partNum}-拍产品相机 视觉算法";
            switch (floor)
            {
                case 1:
                    cam1 = _containerProvider.Resolve<ICameraService>("Floor1Up");
                    break;
                case 2:
                    cam1 = _containerProvider.Resolve<ICameraService>("Floor2Up");
                    break;
                default:
                    break;
            }
            using (var db = new DTContext(partNum))
            {
                var points = db.XYZRPoints.Where(p => (p.Name == "TopCameraBoardOrgGrab" || p.Name == "OrgBoard" || p.Name == "TopCameraCalib" || p.Name == "TopCameraMark1" || p.Name == "TopCameraMark2") && p.Floor == floor);
                if (points.Any())
                {
                    var posList = points.ToList();
                    foreach (var item in posList)
                    {
                        PointList1.Add(
                            new AxisPointDisp
                            {
                                Id = item.Id,
                                Name = item.Name,
                                Alias = item.Alias,
                                X = item.X,
                                Y = item.Y,
                                Z = item.Z,
                                R = item.R,
                                ZIndex = item.ZIndex,
                                RIndex = item.RIndex
                            }
                            );
                    }
                }
                var v1 = db.MParams.FirstOrDefault(p => p.Name == "XJogSpeed" && p.Floor == floor);
                if (v1 != null)
                {
                    xjogspeed = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "YJogSpeed" && p.Floor == floor);
                if (v1 != null)
                {
                    yjogspeed = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "ZJogSpeed" && p.Floor == floor);
                if (v1 != null)
                {
                    zjogspeed = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "RJogSpeed" && p.Floor == floor);
                if (v1 != null)
                {
                    rjogspeed = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "Z1SafePos" && p.Floor == floor);
                if (v1 != null)
                {
                    z1safe = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "Z2SafePos" && p.Floor == floor);
                if (v1 != null)
                {
                    z2safe = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "Z3SafePos" && p.Floor == floor);
                if (v1 != null)
                {
                    z3safe = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "Z4SafePos" && p.Floor == floor);
                if (v1 != null)
                {
                    z4safe = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "Mark1ThresholdMaxGray" && p.Floor == floor);
                if (v1 != null)
                {
                    Mark1ThresholdMaxGray = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "Mark1MinArea" && p.Floor == floor);
                if (v1 != null)
                {
                    Mark1MinArea = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "Mark1MaxArea" && p.Floor == floor);
                if (v1 != null)
                {
                    Mark1MaxArea = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "Mark2ThresholdMaxGray" && p.Floor == floor);
                if (v1 != null)
                {
                    Mark2ThresholdMaxGray = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "Mark2MinArea" && p.Floor == floor);
                if (v1 != null)
                {
                    Mark2MinArea = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "Mark2MaxArea" && p.Floor == floor);
                if (v1 != null)
                {
                    Mark2MaxArea = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "OrgWidth");
                double orgWidth = 0;
                if (v1 != null)
                {
                    orgWidth = double.Parse(v1.Value);
                }
                double orgPX = 0;
                if (v1 != null)
                {
                    orgPX = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "OrgY" && p.Floor == 1);
                double orgPY = 0;
                if (v1 != null)
                {
                    orgPY = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "OrgX" && p.Floor == 2);
                double orgNX = 0;
                if (v1 != null)
                {
                    orgNX = double.Parse(v1.Value);
                }
                v1 = db.MParams.FirstOrDefault(p => p.Name == "OrgY" && p.Floor == 2);
                double orgNY = 0;
                if (v1 != null)
                {
                    orgNY = double.Parse(v1.Value);
                }
                //var grabPoint = PointList1.FirstOrDefault(p => p.Name == "TopCameraBoardOrgGrab");
                var orgPoint = PointList1.FirstOrDefault(p => p.Name == "OrgBoard");                
            }
            using (var sysDb = new SysContext())
            {
                switch (floor)
                {
                    case 1:
                        {
                            var _param = sysDb.MSystemParams.FirstOrDefault(p => p.Name == "Floor1UpCameraGrabPreTime");
                            if (_param != null)
                            {
                                upCameraGrabPreTime = double.Parse(_param.Value);
                            }
                        }
                        break;
                    case 2:
                        {
                            var _param = sysDb.MSystemParams.FirstOrDefault(p => p.Name == "Floor2UpCameraGrabPreTime");
                            if (_param != null)
                            {
                                upCameraGrabPreTime = double.Parse(_param.Value);
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        public override void OnDialogClosed()
        {
            cam1.StopGrabe();
            if (source != null)
            {
                source.Cancel();
            }
        }
        #endregion
        public CameraProductVisionCalcDialogViewModel(IContainerProvider containerProvider) : base(containerProvider)
        {
            _containerProvider = containerProvider;
            Top_A4 = containerProvider.Resolve<IGTSCardService>("Top_A4");
            Top_A8 = containerProvider.Resolve<IGTSCardService>("Top_A8");
            Bottom_A8 = containerProvider.Resolve<IGTSCardService>("Bottom_A8");
            IsBusy = false;
            PointList1 = new ObservableCollection<AxisPointDisp>();
        }
        #region 功能函数
        private void ContinueGrab(CancellationToken token)
        {
            cam1.ImageQueue.Clear();
            cam1.SetTriggerMode(0);
            cam1.StartGrabe();
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    cam1.StopGrabe();
                    return;
                }
                HObject? hObj;
                if (cam1.ImageQueue.TryPeek(out hObj))
                {
                    cam1.ImageQueue.TryDequeue(out hObj);
                    CameraIamge0 = new HImage(hObj);
                }
                System.Threading.Thread.Sleep(1);
            }
        }        
        private void JumpXYZRAction(CancellationToken token, AxisPointDisp point)
        {
            try
            {
                var axisX = floor == 1 ? Top_A8.A1 : Bottom_A8.A1;
                var axisY = floor == 1 ? Top_A8.A2 : Bottom_A8.A2;
                var axisZ1 = floor == 1 ? Top_A8.A4 : Bottom_A8.A4;
                var axisZ2 = floor == 1 ? Top_A8.A5 : Bottom_A8.A5;
                var axisZ3 = floor == 1 ? Top_A8.A6 : Bottom_A8.A6;
                var axisZ4 = floor == 1 ? Top_A8.A7 : Bottom_A8.A7;
                AxisParm axisZ, axisR;
                switch (point.ZIndex)
                {
                    case 0:
                        axisZ = floor == 1 ? Top_A8.A4 : Bottom_A8.A4;
                        break;
                    case 1:
                        axisZ = floor == 1 ? Top_A8.A5 : Bottom_A8.A5;
                        break;
                    case 2:
                        axisZ = floor == 1 ? Top_A8.A6 : Bottom_A8.A6;
                        break;
                    case 3:
                    default:
                        axisZ = floor == 1 ? Top_A8.A7 : Bottom_A8.A7;
                        break;
                }
                switch (point.RIndex)
                {
                    case 0:
                        axisR = floor == 1 ? Top_A4.A1 : Top_A4.A3;
                        break;
                    case 1:
                    default:
                        axisR = floor == 1 ? Top_A4.A2 : Top_A4.A4;
                        break;
                }
                int stepnum = 0;
                while (true)
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    switch (stepnum)
                    {
                        case 0://Z运动到安全位
                            {
                                GTSCard.AxisPosMove(ref axisZ1, z1safe, zjogspeed);
                                GTSCard.AxisPosMove(ref axisZ2, z2safe, zjogspeed);
                                GTSCard.AxisPosMove(ref axisZ3, z3safe, zjogspeed);
                                GTSCard.AxisPosMove(ref axisZ4, z4safe, zjogspeed);
                                stepnum = 1;
                            }
                            break;
                        case 1:
                            if (GTSCard.AxisPosMoveCheckDone(axisZ1) && GTSCard.AxisPosMoveCheckDone(axisZ2) && GTSCard.AxisPosMoveCheckDone(axisZ3) && GTSCard.AxisPosMoveCheckDone(axisZ4))
                            {
                                stepnum = 2;
                            }
                            break;
                        case 2:
                            {
                                GTSCard.AxisPosMove(ref axisX, point.X, xjogspeed);
                                GTSCard.AxisPosMove(ref axisY, point.Y, yjogspeed);
                                GTSCard.AxisPosMove(ref axisR, point.R, rjogspeed);
                                stepnum = 3;
                            }
                            break;
                        case 3:
                            if (GTSCard.AxisPosMoveCheckDone(axisX) && GTSCard.AxisPosMoveCheckDone(axisY) && GTSCard.AxisPosMoveCheckDone(axisR))
                            {
                                stepnum = 4;
                            }
                            break;
                        case 4:
                            {
                                GTSCard.AxisPosMove(ref axisZ, point.Z, zjogspeed);
                                stepnum = 5;
                            }
                            break;
                        case 5:
                            if (GTSCard.AxisPosMoveCheckDone(axisZ))
                            {
                                return;
                            }
                            break;
                        default:
                            break;
                    }
                    System.Threading.Thread.Sleep(100);
                }
            }
            catch (Exception ex)
            {
                //logger.Error(ex);
                Debug.WriteLine(ex.Message);
            }

        }
        #endregion
    }
}
